package repository

import (
	"context"
	"encoding/json"
	"fmt"
	"time"

	"github.com/go-redis/redis/v8"
)

type redisCacheProvider struct {
	client *redis.Client
	ttl    time.Duration
	prefix string
}

func NewRedisCacheProvider(client *redis.Client, ttl time.Duration) *redisCacheProvider {
	return &redisCacheProvider{
		client: client,
		ttl:    ttl,
		prefix: "cache:",
	}
}

func (r *redisCacheProvider) Set(ctx context.Context, key string, value interface{}) error {
	data, err := json.Marshal(value)
	if err != nil {
		return err
	}
	return r.client.Set(ctx, r.prefix+key, data, r.ttl).Err()
}

func (r *redisCacheProvider) Get(ctx context.Context, key string) (interface{}, error) {
	data, err := r.client.Get(ctx, r.prefix+key).Bytes()
	if err == redis.Nil {
		return nil, nil
	} else if err != nil {
		return nil, err
	}

	var value interface{}
	if err := json.Unmarshal(data, &value); err != nil {
		return nil, err
	}
	return value, nil
}

func (r *redisCacheProvider) Delete(ctx context.Context, key string) error {
	return r.client.Del(ctx, r.prefix+key).Err()
}

// AddToIndex 添加值到索引
func (r *redisCacheProvider) AddToIndex(ctx context.Context, indexName, indexValue string, primaryKey interface{}) error {
	indexKey := r.indexKey(indexName, indexValue)
	return r.client.SAdd(ctx, indexKey, primaryKey).Err()
}

// GetFromIndex 从索引获取值
func (r *redisCacheProvider) GetFromIndex(ctx context.Context, indexName, indexValue string) ([]interface{}, error) {
	indexKey := r.indexKey(indexName, indexValue)
	return r.client.SMembers(ctx, indexKey).Result()
}

// RemoveFromIndex 从索引移除值
func (r *redisCacheProvider) RemoveFromIndex(ctx context.Context, indexName, indexValue string, primaryKey interface{}) error {
	indexKey := r.indexKey(indexName, indexValue)
	return r.client.SRem(ctx, indexKey, primaryKey).Err()
}

// indexKey 生成索引键
func (r *redisCacheProvider) indexKey(indexName, indexValue string) string {
	return fmt.Sprintf("%sindex:%s:%s", r.prefix, indexName, indexValue)
}

func (r *redisCacheProvider) Stats() CacheStats {
	// Redis统计需要额外实现
	return CacheStats{}
}

func (r *redisCacheProvider) CleanExpired(ctx context.Context) error {
	// Redis自动处理过期
	return nil
}
